#include "fighter_yann.hpp"
#include "player.hpp"

using namespace Shiny;
using namespace Shiny::Applejack;

FighterYann::FighterYann(World& w, Body& b, Applejack::View* camera) : Player(w, b, camera)
{
    _damageResistance = 60;
    _speed            = 100;
    _strength         = 7;

    _isSeducting      = false;

    Shiny::TextureList* tex = _world.Hud()->GetTextureList();

    if (tex)
    {
	AddSpellDisplay(spell1, 0, (*tex)["spell-seduction"]);
	AddSpellDisplay(spell2, 1, (*tex)["spell-insult"]);
	AddSpellDisplay(spell3, 2, (*tex)["spell-gringalet"]);
	AddSpellDisplay(spell4, 3, (*tex)["spell-patate"]);
    }

    Shiny::SoundList& sounds  = _world.GetSounds();
    const sf::SoundBuffer*  victory = sounds["yann-victory"];

    if (victory)      _soundVictory.SetBuffer(*victory);
}

void FighterYann::Victory(bool hasWon)
{
    if (hasWon && _soundVictory.GetBuffer())
	SoundManager::Get()->Play(&_soundVictory);
    else if (!hasWon)
    {
	this->Stun(999999.f);
	delete _body.Fixture("body");
    }
}

void FighterYann::GetKicked(int damage, const Attack::Effects& effects)
{
  Player::GetKicked(damage, effects);
}

void FighterYann::SpellFirst(sf::Event)
{
    if (!_isSeducting && _cooldownSeduction.GetElapsedTime().AsSeconds() > CooldownSeduction)
    {
	b2Vec2       bodyPos = _body.PhysicBody()->GetWorldCenter();
	sf::Vector2f point1(bodyPos.x, bodyPos.y);
	sf::Vector2f point2(point1);

	point2.x        += (_lookingLeft ? -1000.f : 1000.f);
	seductionRaycast = new Applejack::World::RayCastObserver(_world, point1, point2, Applejack::World::RayCastObserver::Closest);
	seductionRaycast->Connect(*this, &FighterYann::SeductionContact);
	_isSeducting     = true;
	_body.Sprite().SetAnimation(6);
	_animationSeductionObserver = _body.Sprite().AnimationFinished.Connect(*this, &FighterYann::EndAnimationSeduction);
    }
}

void FighterYann::AnimationInterupted()
{
    _body.Sprite().AnimationFinished.Disconnect(_animationSeductionObserver);
    Player::AnimationInterupted();
}

void FighterYann::InterruptChannelling()
{
    if (_isSeducting)
	EndSeduction();
    SetDefaultAnimation();
}

void FighterYann::EndSeduction()
{
    seductionRaycast->DeleteLater();
    _isSeducting = false;
    _cooldownSeduction.Restart();
}

void FighterYann::EndAnimationSeduction(unsigned int)
{
    if (_isSeducting)
	EndSeduction();
    _body.Sprite().AnimationFinished.Disconnect(_animationSeductionObserver);
}

void FighterYann::SeductionContact(Shiny::Applejack::World::RayCastCollisions collisions)
{
    if (_isSeducting && collisions.size() > 0)
    {
	Fixture* fixture = collisions.begin()->fixture;
	Body&    body    = fixture->GetBody();
	IA*      ia      = body.GetIA();

	if (ia)
	{
	    Player* playerIa = reinterpret_cast<Player*>(ia);
	    Attack::Effects effects;

	    _life += 30.f;
	    LifeUpdated.Emit(_life);
	    effects.push_back(Attack::Effect(Attack::Effect::STUN, 100.f, 0.f));
	    playerIa->GetKicked(30, effects);
	    EndSeduction();
	}
    }
}

void FighterYann::SpellSecond(sf::Event)
{
}

void FighterYann::SpellThird(sf::Event)
{
}

void FighterYann::SpellUltimate(sf::Event)
{
}

void FighterYann::Run(void)
{
    DisplaySpells();
    Player::Run();
}

void FighterYann::DisplaySpells()
{
    UpdateSpellProgressBar(_cooldownSeduction.GetElapsedTime().AsSeconds(), CooldownSeduction, spell1);
    UpdateSpellProgressBar(_cooldownBarman.GetElapsedTime().AsSeconds(), CooldownBarman, spell2);
    UpdateSpellProgressBar(_cooldownComics.GetElapsedTime().AsSeconds(), CooldownComics, spell3);
    UpdateSpellProgressBar(_cooldownEliot.GetElapsedTime().AsSeconds(), CooldownEliot, spell4);
}
